package com.knight.handler;


import com.sun.org.slf4j.internal.Logger;
import com.sun.org.slf4j.internal.LoggerFactory;

/**
 * @param <E> 事件消息类型
 * @param <T> 事件消息源
 */
public abstract class AbstractEventHandler<E, T> implements EventHandler<E, T> {

    private Logger log = LoggerFactory.getLogger(this.getClass());


    public void handler(T eventData) {
        try {
            log.debug("事件消息处理器{}开始处理消息:", getHandlerName());
            boolean flag = this.doHandler(eventData);
            if(flag) {
                doHandlerSuccess();
            }else {
                doHandlerFailed(eventData,null);
            }
        } catch (Exception e) {
            log.error("事件消息异常:{}",e.getMessage());
            e.printStackTrace();
            doHandlerFailed(eventData,e);
        } finally {
            log.debug("事件消息处理完毕，进行资源释放操作");
            release();//扩展的释放操作
            releaseResource();
        }
    }

    /**
     * 具体业务逻辑处理地方
     *
     * @return
     */
    abstract boolean doHandler(T data);


    /**
     * 处理成功以后流程
     */
    public void doHandlerSuccess() {

    }

    /**
     * 处理失败以后的流程
     */
    public void doHandlerFailed(T data,Exception exception) {
        //TODO 进行处理方法重试 ,后期考虑采用spring-retry模块来执行重试
        //如果有重试机制，执行重试流程
        //如果没有重试机制，或者已经完成重试，依然失败的情况下，进行事件执行失败记录入库

        //失败分为俩种情况，1.业务逻辑失败 2.程序执行异常

    }

    /**
     * 提供自定义的释放方法，允许扩展
     */
    abstract void release();

    /**
     * 最终需要进行释放占用的资源
     */
    public void releaseResource() {

    }

    /**
     * 默认提供序号为0
     * @return
     */
    @Override
    public Integer getOrder() {
        return 0;
    }
}
